package top.broncho.mvvm.util

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.annotation.MainThread
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


suspend inline fun AppCompatActivity.pickImage() =
    suspendCoroutine<Uri?> { continuation ->
        PickImageManager.requestImage(this) {
            continuation.resume(this)
        }
    }

suspend inline fun Fragment.pickImage() =
    suspendCoroutine<Uri?> { continuation ->
        PickImageManager.requestImage(this) {
            continuation.resume(this)
        }
    }

/**
 * A simple [Fragment] subclass.
 */
class PickImageManager : Fragment() {
    private var resultCallback: (Uri?.() -> Unit)? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE) onResult(data?.data)
    }


    fun startPick(resultCallback: Uri?.() -> Unit) {
        this.resultCallback = resultCallback
        val intent = Intent(Intent.ACTION_PICK).apply {
            type = "image/*"
        }
        startActivityForResult(
            intent,
            REQUEST_CODE
        )
    }

    private fun onResult(uri: Uri?) {
        resultCallback?.invoke(uri)

    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        resultCallback = null
    }

    override fun onDestroy() {
        super.onDestroy()
        resultCallback = null
    }

    companion object {

        private const val TAG = "PickImageManager"
        private const val REQUEST_CODE = 42


        @JvmStatic
        @MainThread
        fun requestImage(
            activity: AppCompatActivity,
            resultCallback: Uri?.() -> Unit
        ) {
            getImageFragment(activity.supportFragmentManager).apply {
                startPick(resultCallback)
            }

        }

        @JvmStatic
        @MainThread
        fun requestImage(
            fragment: Fragment,
            resultCallback: Uri?.() -> Unit
        ) {
            getImageFragment(fragment.childFragmentManager).apply {
                startPick(resultCallback)
            }
        }

        private fun getImageFragment(fragmentManager: FragmentManager): PickImageManager {
            var fragment = fragmentManager.findFragmentByTag(TAG)
            if (fragment != null) {
                fragment = fragment as PickImageManager
            } else {
                fragment = PickImageManager()
                fragmentManager.beginTransaction().add(fragment, TAG).commitNow()
            }
            return fragment
        }
    }

}